#include <benchmark/benchmark.h>
#include <vector>
#include <string>

struct Heavy {
    std::string a, b, c;
    Heavy(std::string x, std::string y, std::string z)
        : a(std::move(x)), b(std::move(y)), c(std::move(z)) {}
};

static void VectorPushBack(benchmark::State& state) {
    for (auto _ : state) {
        std::vector<Heavy> vec;
        vec.reserve(state.range(0));
        for (int i = 0; i < state.range(0); ++i) {
            Heavy tmp("abcdefgh", "ijklmnop", "qrstuvwx"); // 生成临时拷贝
            vec.push_back(tmp);
        }
        benchmark::ClobberMemory();
    }
}
BENCHMARK(VectorPushBack)->RangeMultiplier(2)->Range(64, 1 << 16);

static void VectorPushBackMove(benchmark::State& state) {
    for (auto _ : state) {
        std::vector<Heavy> vec;
        vec.reserve(state.range(0));
        for (int i = 0; i < state.range(0); ++i) {
            vec.push_back(Heavy("abcdefgh", "ijklmnop", "qrstuvwx")); // 先构造再移动
        }
        benchmark::ClobberMemory();
    }
}
BENCHMARK(VectorPushBackMove)->RangeMultiplier(2)->Range(64, 1 << 16);

static void VectorEmplaceBack(benchmark::State& state) {
    for (auto _ : state) {
        std::vector<Heavy> vec;
        vec.reserve(state.range(0));
        for (int i = 0; i < state.range(0); ++i) {
            vec.emplace_back("abcdefgh", "ijklmnop", "qrstuvwx"); // 原位构造
        }
        benchmark::ClobberMemory();
    }
}
BENCHMARK(VectorEmplaceBack)->RangeMultiplier(2)->Range(64, 1 << 16);

BENCHMARK_MAIN();